from typing import List, Optional
from datetime import datetime
import secrets

from fastapi import HTTPException
from sqlalchemy import func
from sqlalchemy.orm import Session, Query

from app.models import Chat
from app.models.ai import AIAgentGroup, AIApiKey, AIModel, AIAgent, Tools


class AIService:

    @staticmethod
    def getAILLMInfo(db: Session, chat_id: int) -> tuple[Chat, AIAgent, AIModel, AIApiKey]:
        """获取模型等信息"""
        if chat_id is None:
            return (None, None, None, None)
        _result = (db.query(Chat, AIAgent, AIModel, AIApiKey).outerjoin(AIAgent, AIAgent.id == Chat.ai_agent_id)
                   .outerjoin(AIModel, AIModel.id == AIAgent.ai_model_id)
                   .outerjoin(AIApiKey, AIApiKey.id == AIModel.ai_api_id)
                   .filter(Chat.id == chat_id).first()
                   )
        if _result:
            chat, aiAgent, aiModel, aiApi = _result
            return (chat, aiAgent, aiModel, aiApi)
        return (None, None, None, None)

    @staticmethod
    def getAILLMInfoByAIAgentId(db: Session, ai_agent_id: int) -> tuple[AIAgent, AIModel, AIApiKey]:
        """获取模型信息"""
        if ai_agent_id is None:
            return (None, None, None)
        _result = (db.query(AIAgent, AIModel, AIApiKey)
                   .outerjoin(AIModel, AIModel.id == AIAgent.ai_model_id)
                   .outerjoin(AIApiKey, AIApiKey.id == AIModel.ai_api_id)
                   .filter(AIAgent.id == ai_agent_id).first()
                   )
        if _result:
            aiAgent, aiModel, aiApi = _result
            return (aiAgent, aiModel, aiApi)
        return (None, None, None)


    @staticmethod
    def get_ai_model_view_info(db: Session, ai_model_id: int) -> tuple[str, AIModel, AIApiKey]:
        if ai_model_id is None:
            return ('', None, None)
        _result = (db.query(AIModel, AIApiKey).outerjoin(AIApiKey, AIModel.ai_api_id == AIApiKey.id)
                   .filter(AIModel.id == ai_model_id).first()
                   )
        if _result:
            aiModel, aiApi = _result
            return (AIService.format_ai_model_view_info(aiModel, aiApi), aiModel, aiApi)
        return ('', None, None)

    @staticmethod
    def format_ai_model_view_info(aiModel: AIModel, aiApi: AIApiKey) -> str:
        if AIModel is None:
            return ''
        if aiApi is None:
            return ''
        return f'{aiApi.description}-{aiModel.model_name}'


    @staticmethod
    def format_tools_info(db: Session, tools_ids: str) -> list[str] | None:
        if tools_ids is None or tools_ids == '':
            return None
        _result = (db.query(Tools)
                   .filter(func.find_in_set(Tools.id, tools_ids)).all())
        if _result is None:
            return None

        _tmp = []
        for tool in _result:
            # strInfo=f'[{tool.tool_name}]{tool.tool_desc}'
            strInfo=f'{tool.tool_name}'
            _tmp.append(strInfo)
        return _tmp
    @staticmethod
    def format_agent_ids_info(db: Session, agent_ids: str) -> list[str] | None:
        if agent_ids is None or agent_ids == '':
            return None
        _result = (db.query(AIAgent, AIModel, AIApiKey)
                   .outerjoin(AIModel, AIModel.id == AIAgent.ai_model_id)
                   .outerjoin(AIApiKey, AIApiKey.id == AIModel.ai_api_id)
                   .filter(func.find_in_set(AIAgent.id, agent_ids)).all())
        if _result is None:
            return None

        _tmp = []
        for aiAgent, aiModel, aiApi in _result:
            if aiAgent is None:
                continue
            _str = f'{aiAgent.emoji}[{aiAgent.name}]'
            _tmp.append(_str)

            # _tmp.append(AIService.format_ai_agent_view_info(aiAgent, aiModel, aiApi))
        return _tmp

    @staticmethod
    def get_ai_agent_view_info(db: Session, ai_agent_id: int) -> tuple[str, AIAgent, AIModel, AIApiKey]:
        if ai_agent_id is None:
            return ('', None, None, None)
        _result = (db.query(AIAgent, AIModel, AIApiKey)
                   .outerjoin(AIModel, AIModel.id == AIAgent.ai_model_id)
                   .outerjoin(AIApiKey, AIApiKey.id == AIModel.ai_api_id)
                   .filter(AIAgent.id == ai_agent_id).first())
        if _result is None:
            return ('', None, None, None)
        aiAgent, aiModel, aiApi = _result
        return (AIService.format_ai_agent_view_info(aiAgent, aiModel, aiApi), aiAgent, aiModel, aiApi)

    @staticmethod
    def format_ai_agent_view_info(aiAgent: AIAgent, aiModel: AIModel, aiApi: AIApiKey) -> str:
        if aiAgent is None:
            return ''
        _str = f'{aiAgent.emoji}[{aiAgent.name}]'
        if aiModel is None:
            return _str
        _str += f'{aiApi.description}-{aiModel.model_name}'
        return _str


class AIAgentGroupService:

    @staticmethod
    def get_ai_agent_group_list_format_dict(db: Session) -> list:
        """格式化成字典格式的列表"""
        conditions = []
        query: Query = (db.query(AIAgentGroup)
                        .filter(*conditions)
                        )

        rows = (
            query
            .order_by(AIAgentGroup.id.asc())
            .all()
        )
        data = rows
        return data

    @staticmethod
    def auto_create_ai_agent_group(db: Session, user_id: int, groups: str):
        if groups is None or groups == '':
            return
        for group in groups.split(','):
            data = AIAgentGroupService.get_ai_agent_group(db, group)
            if data:
                pass
            else:
                AIAgentGroupService.create_ai_agent_group(db, user_id, group)

    @staticmethod
    def get_ai_agent_group(db: Session, group: str) -> AIAgentGroup:
        return (
            db.query(AIAgentGroup)
            .filter(AIAgentGroup.group == group)
            .first()
        )

    @staticmethod
    def create_ai_agent_group(db: Session, user_id: int, group: str) -> AIAgentGroup:
        """含逗号的需要调用 auto_create_ai_agent_group """
        if ',' in group:
            raise HTTPException(status_code=400, detail="分组不能包含逗号")
        data = AIAgentGroup(
            group=group,
            user_id=user_id,
        )
        db.add(data)
        db.commit()
        db.refresh(data)
        return data
